# -*- coding: utf-8 -*-
# &&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&
# odoo16
# QQ:35350428
# 邮件:35350428@qq.com
# 手机：13584935775
# 作者：'Amos'
# 公司网址： www.xodoo.cn
# Copyright 昆山一百计算机有限公司
# 日期：2023-09-16
# &&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&

from odoo import api, fields, models, tools, SUPERUSER_ID, _
from odoo.exceptions import AccessDenied, AccessError, UserError, ValidationError
from lxml import etree
from odoo.osv import expression
from datetime import datetime, timedelta, time

global global_context

class workflow_approval(models.Model):
    _name = 'workflow.approval'
    _description = '下级审核人'
    _order = 'id desc'

    @api.depends('state', 'check_user_ids')
    def _get_check_user_count(self):
        for order in self:
            order.update({
                'check_user_count': len(order.check_user_ids._ids),
            })

    """
    当前用户，所在模块，所在状态，提交后，他的审核人
    如果走的流程可以清除当前的权限，也可以执行方法一次性计算他的审核人，通过默认规则进行计算
    """

    @api.model
    def default_get(self, fields):
        """
        是否显示确认与拒绝
        :param fields:
        :return:
        """
        res = super(workflow_approval, self).default_get(fields)
        context = dict(self._context or {})

        #::::判断是不是批量审批如果是 计算所有表单状态是否一致，是否有审批规则
        #:::::是否批量审核
        if context.get('batch'):
            workflow_user_ids = []
            #::::批量审批
            active_id = context.get('active_id')
            active_model = context.get('active_model')
            order = self.env[active_model].browse(active_id)
            #:::::1,所有的单据类型一致

            query = "select state,count(*) from {} where id in %s group by state".format(order._table)
            self._cr.execute(query, [tuple(context['active_ids'])])

            rows = dict(self._cr.fetchall())
            if len(rows) > 1:
                raise UserError('警告：您选择了至少 [%s] 种状态！' % len(rows))

            #:::::2,下级审批人要存在

            domain = [('model', '=', order._name), ('user_id', '=', self._uid)]
            process = self.env['workflow'].sudo().search(domain, order="id desc", limit=1)
            if process:
                line = process.process_ids.filtered(
                    lambda o: o.state_form == order.state)
                if len(line) > 1:
                    raise UserError('警告：系统流程配置错误！')
                if line:
                    process_user_ids = line.users_ids
                    if line.is_department:
                        domain_power = [('power_id.name', 'in', line.power.split(',')),
                                        ('department_id', '=', order.department_id.id)]
                        workflow_user_ids = self.env['hr.department.power'].sudo().search(domain_power)
                        if not workflow_user_ids:
                            raise UserError('警告：当前部门:%s 不存在 %s 角色' % (order.department_id.name, str(line.power)))
                    elif line.is_company:
                        domain_power = [('power_id.name', 'in', line.power.split(',')),
                                        ('company_id', '=', order.company_id.id)]
                        workflow_user_ids = self.env['hr.department.power'].sudo().search(domain_power)
                        if not workflow_user_ids:
                            raise UserError('警告：当前公司:%s 不存在 %s 角色' % (order.department_id.name, str(line.power)))
                    else:
                        domain_power = [('power_id.name', 'in', line.power.split(','))]
                        workflow_user_ids = self.env['hr.department.power'].sudo().search(domain_power)
                        if not workflow_user_ids:
                            raise UserError('警告：当前系统:%s 不存在 %s 角色' % (order.department_id.name, str(line.power)))
                context['form_state'] = line.state_form  # 从状态
                context['to_state'] = line.state_to  # 到状态
                context['next_state'] = line.state_next  # 下级状态
            else:
                domain = [('model', '=', order._name)]
                process = self.env['workflow'].sudo().search(domain, order="id desc", limit=1)
                line = process.process_ids.filtered(
                    lambda o: o.state_form == order.state)
                if len(line) > 1:
                    raise UserError('警告：系统流程配置错误！')
                if line:
                    if line.is_department:
                        domain_power = [('power_id.name', 'in', line.power.split(',')),
                                        ('department_id', '=', order.department_id.id)]
                        workflow_user_ids = self.env['hr.department.power'].sudo().search(domain_power)
                        if not workflow_user_ids:
                            raise UserError('警告：当前部门:%s 不存在 %s 角色' % (order.department_id.name, str(line.power)))
                    elif line.is_company:
                        domain_power = [('power_id.name', 'in', line.power.split(',')),('company_id', '=', order.company_id.id)]
                        workflow_user_ids = self.env['hr.department.power'].sudo().search(domain_power)
                        if not workflow_user_ids:
                            raise UserError('警告：当前公司:%s 不存在 %s 角色' % (order.department_id.name, str(line.power)))
                    else:
                        domain_power = [('power_id.name', 'in', line.power.split(','))]
                        workflow_user_ids = self.env['hr.department.power'].sudo().search(domain_power)
                        if not workflow_user_ids:
                            raise UserError('警告：当前系统:%s 不存在 %s 角色' % (order.department_id.name, str(line.power)))
                context['form_state'] = line.state_form  # 从状态
                context['to_state'] = line.state_to # 到状态
                context['next_state'] = line.state_next # 下级状态
            #:::::3,状态也要存在 这里判断写死吧，还是扩展加一个跳转字段
            user_ids = []
            if workflow_user_ids:
                for line in workflow_user_ids:
                    user_ids.append(line.user_id.id)

            #::::去重
            if user_ids:
                user_ids = list(set(user_ids))

            context['workflow_user_ids'] = user_ids
            context['mult_confirm'] = False  # 是不是流程中节点审核
            context['default_type'] = '汇签'  # 只要一个人审批即可

            self = self.with_context(dict(context))
            values = {}
            values['name'] = ''

            if context.get('workflow_user_ids'):
                lines = []
                for user_id in context.get('workflow_user_ids'):
                    pram = {
                        'user_id': user_id,
                    }
                    lines.append((0, 0, pram))

                values['check_user_ids'] = lines

            self = self.with_context(dict(context))
            res.update(values)
            global_context = context
        else:
            if context.get('message_type',False) == 'A':
                pass
            else:

                active_id = context.get('active_id')
                active_model = context.get('active_model')
                # order = self.env[active_model].browse(active_id)

                values = {}
                values['name'] = ''
                if context.get('stop_flow') == True:
                    # res.update({'is_process_node': context.get('stop_flow'), })
                    values['is_process_node'] = context.get('stop_flow')
                else:
                    # res.update({'is_process_node': context.get('mult_confirm'), })
                    values['is_process_node'] = context.get('mult_confirm')

                if "is_yes" in context:
                    res.update({'is_yes': context['is_yes'], })

                if "workflow_type" in context:
                    res.update({'type': context['workflow_type'], })

                if "is_no" in context:
                    res.update({'is_no': context.get('is_no'), })

                if "my_tips" in context:
                    res.update({'my_tips': context.get('my_tips'), })

                if context.get('workflow_user_ids'):
                    lines = []
                    for user_id in context.get('workflow_user_ids'):
                        pram = {
                            'user_id': user_id,
                        }
                        lines.append((0, 0, pram))

                    values['check_user_ids'] = lines

                #远程调用接口返回
                if context.get('call_workflow') == True:
                    return context

                self = self.with_context(dict(context))
                res.update(values)

        return res

    name = fields.Text(string='原因')
    is_yes = fields.Boolean(default=True, string='显示确认')
    is_no = fields.Boolean(default=True, string='显示拒绝')
    is_process_node = fields.Boolean(default=False, string='审批中间过程')
    user_id = fields.Many2one('res.users', string='用户', default=lambda self: self.env.user)
    model = fields.Char(string='对象')
    form_state = fields.Char(string='从状态')
    to_state = fields.Char(string='到状态')
    users_ids = fields.Many2many('res.users', 'workflow_approval_res_users_rel', 'process_id', 'user_id',
                                 string='消息通知人')
    code = fields.Char(string='自定义代码')
    type = fields.Selection([
        ('串签', '串签'),
        ('并签', '并签'),
        ('汇签', '汇签'),
    ], string='类型', default='串签', help="""串签、并签、汇签，也就是
        串流、并流、择流。
        假设一份文件需要A、B两个主管来审批，那么，
        串签：A签完，才轮到B来签；一般A是小领导，B是大领导；
        并签：A和B是并列的，可同时签，但必须2人都要签；一般A和B是同一层级但不同部门领导
        汇签：A和B是并列的，但只需一个签就可以了；此处A、B就是完全等价的了""")

    state = fields.Selection([
        ('同意', '同意'),
        ('拒绝', '拒绝'),
    ], string='审批类型', default='同意')
    check_user_ids = fields.One2many('workflow.approval.line', 'order_id', string='审核人')
    check_user_count = fields.Integer(string='审核人数量', compute='_get_check_user_count', readonly=True)
    my_tips = fields.Char(string='提示', default=lambda self: self.env.context.get('my_tips'))
    warning = fields.Char(string='提醒：请添加下级审批人')

    # @api.model
    # def create(self, vals):
    #     context = dict(self._context or {})
    #     result = super(workflow_approval, self.with_context(context)).create(vals)
    #     return result

    def but_confirm(self):
        context = dict(self._context or {})
        if context.get('batch'):

            context = dict(global_context) + context
            active_ids = context.get('active_ids')
            for active_id in active_ids:
                context['stop_flow']=False
                context['type_flows']='button'
                context['wkf']='workflow_ok,workflow_no'
                context['active_id']=active_id

                self.with_context(dict(context)).common_confirm()
        else:

            o_o_type = self._context['type_flows'].split(',')
            if len(o_o_type) > 1:
                self._context['type_flows'] = o_o_type[0]

            if self._context['active_model'] == '自定义对象':
                pass
            else:
                self.common_confirm()

        return True

    def but_cancel(self):

        if self.name == False:
            raise UserError('拒绝一定要写明原因!')

        o_o_type = self._context['type_flows'].split(',')
        if len(o_o_type) > 1:
            self._context['type_flows'] = o_o_type[1]
        if self._context['active_model'] == '自定义对象':
            pass
        else:
            self.common_cancel()

        return {'type': 'ir.actions.act_window_close'}



    def common_confirm(self):
        """
        向导介面执行确认
        """
        context = dict(self._context or {})
        # 界面按钮上增加审批
        if context.get('approval_state') == '同意':
            obj = self.env[self._context['active_model']]
            #::工作流通知人
            context = dict(self._context or {})
            if self.is_process_node and context.get('stop_flow', False) == False:
                context['is_process_node'] = self.is_process_node
            else:
                workflow_partner_ids = []
                workflow_users_ids = []
                workflow_users_str = []
                workflow_partner_name = []
                messages_partner_ids = []
                messages_users_ids = []
                messages_partner_name = []

                #定义审批流
                values = []
                sequence = 1
                lines = []
                records_model = self.env['ir.model'].sudo().search([('model', '=', obj._name)], limit=1)

                check_user_ids = self.env['workflow.approval.line'].with_context(lang=None).sudo().search([('order_id', '=', self.id)])



                for x in check_user_ids:
                    if x.is_message:
                        workflow_users_ids.append(x.user_id.id)
                        workflow_users_str += '%s,' % x.user_id.id
                        workflow_partner_ids.append(x.user_id.partner_id.id)
                        workflow_partner_name.append(x.user_id.name)

                # TODO(amos): 发消息
                for x in self.users_ids:
                    messages_partner_ids.append(x.partner_id.id)
                    messages_partner_name.append(x.partner_id.name)

                #::::去重
                if len(workflow_users_ids) != len(set(workflow_users_ids)):
                    raise UserError('警告：审核人重复！')
                else:
                    pass

                # if workflow_users_ids:
                #     workflow_users_ids = list(set(workflow_users_ids))
                if workflow_partner_ids:
                    workflow_partner_ids = list(set(workflow_partner_ids))
                if workflow_partner_name:
                    workflow_partner_name = list(set(workflow_partner_name))
                if messages_partner_ids:
                    messages_partner_ids = list(set(messages_partner_ids))
                if messages_users_ids:
                    messages_users_ids = list(set(messages_users_ids))
                if messages_partner_name:
                    messages_partner_name = list(set(messages_partner_name))


                context['workflow_partner_ids'] = workflow_partner_ids
                context['workflow_users_ids'] = workflow_users_ids
                context['workflow_users_str'] = workflow_users_str
                context['workflow_partner_name'] = workflow_partner_name
                context['messages_partner_ids'] = messages_partner_ids
                context['messages_users_ids'] = messages_users_ids
                context['messages_partner_name'] = messages_partner_name
                context['type'] = self.type
                context['workflow_approval_id'] = self.id
                context['is_process_node'] = self.is_process_node
                context['version_id'] = datetime.strptime(str(datetime.now()), '%Y-%m-%d %H:%M:%S.%f')

            if self._context['type_flows'] == "button":
                getattr(obj, self._context['wkf'].split(',')[0])(context)

            elif self._context['type_flows'] == "action":
                obj.signal_workflow([int(self._context['active_id'])])

            elif self._context['type_flows'] == "object":
                pass
        else:
            self.common_cancel()

        return True

    def common_cancel(self):

        if not self.name:
            raise UserError('警告：请输入审批建议')

        #::拒绝工作流通知人
        workflow_partner_ids = []
        for x in self.users_ids:
            workflow_partner_ids.append(x.partner_id.id)

        context = dict(self._context or {})
        context['workflow_approval_id'] = self.id
        context['workflow_partner_ids'] = workflow_partner_ids

        obj = self.env[self._context['active_model']]

        if self._context['type_flows'] == "button":
            getattr(obj, self._context['wkf'].split(',')[1])(context)

        elif self._context['type_flows'] == "action":
            obj.signal_workflow([int(self._context['active_id'])])
        elif self._context['type_flows'] == "object":
            pass
        return True


class workflow_approval_line(models.Model):
    _name = 'workflow.approval.line'
    _description = '下级审核人'
    _order = 'sequence asc'


    """
    保存好用户信息下次调用
    """
    sequence = fields.Integer(string='排序', default=10)
    user_id = fields.Many2one('res.users', string='用户')
    order_id = fields.Many2one('workflow.approval', string='明细', ondelete='cascade', index=True, copy=False)
    is_message = fields.Boolean(default=True, string='是送消息')
